

#region Using Statements
using System;
using System.IO;
using System.Diagnostics;
using System.Collections.Generic;
using Microsoft.Build.Construction;
using Microsoft.Build.Evaluation;
using Microsoft.Build.Execution;
using Microsoft.Build.Framework;
#endregion

namespace FoodWar.LevelBuilder
{
    /// <summary>
    /// This class wraps the MSBuild functionality needed to build XNA Framework
    /// content dynamically at runtime. It creates a temporary MSBuild project
    /// in memory, and adds whatever content files you choose to this project.
    /// It then builds the project, which will create compiled .xnb content files
    /// in a temporary directory. After the build finishes, you can use a regular
    /// ContentManager to load these temporary .xnb files in the usual way.
    /// </summary>
    class GameBuilder : IDisposable
    {
        #region Fields



        // MSBuild objects used to dynamically build content.
        Project buildProject;
        ProjectRootElement projectRootElement;
        BuildParameters buildParameters;
        List<ProjectItem> projectItems = new List<ProjectItem>();
        ErrorLogger errorLogger;


        // Temporary directories used by the content build.
        string buildDirectory;
        // Have we been disposed?
        bool isDisposed;
        #endregion

        #region Properties

        public delegate void ProgressChangedNotifier(string progress);
        public event ProgressChangedNotifier BuildFinished;
        
        /// <summary>
        /// Gets the output directory, which will contain the generated .xnb files.
        /// </summary>
        public string OutputDirectory
        {
            get { return buildProject.GetPropertyValue("OutputPath"); }
            set { buildProject.SetProperty("OutputPath", value); }
        }


        #endregion

        #region Initialization
        /// <summary>
        /// Creates a new content builder.
        /// </summary>
        public GameBuilder(string projectPath)
        {
            CreateBuildProject(projectPath);           
        }


        /// <summary>
        /// Finalizes the content builder.
        /// </summary>
        ~GameBuilder()
        {
            Dispose(false);
        }


        /// <summary>
        /// Disposes the content builder when it is no longer required.
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            
            GC.SuppressFinalize(this);
        }


        /// <summary>
        /// Implements the standard .NET IDisposable pattern.
        /// </summary>
        protected virtual void Dispose(bool disposing)
        {
            if (!isDisposed)
            {
                isDisposed = true;
            }
        }
        #endregion

        #region MSBuild


        /// <summary>
        /// Creates a temporary MSBuild content project in memory.
        /// </summary>
        private void CreateBuildProject(string projectPath)
        {

            

            // Create the build project.
            projectRootElement = ProjectRootElement.Open(projectPath);

            
            buildProject = new Project(projectRootElement);
            
           
            // Hook up our custom error logger.
            errorLogger = new ErrorLogger();
            
            buildParameters = new BuildParameters(ProjectCollection.GlobalProjectCollection);
            buildParameters.Loggers = new ILogger[] { errorLogger };
        }


        public void SaveProject()
        {
            buildProject.Save();
        }

        public void AddLevel(string path)
        {
           ProjectItemElement pie =  this.projectRootElement.AddItem("Content", path);
            pie.AddMetadata("CopyToOutputDirectory", "PreserveNewest");
        }

        #endregion
    }
}
